import { ICrawlerEngine } from '@weubi/engines';
import { HttpEngine } from './HttpEngine';
import { logger } from '../utils/logger';

// 动态导入可选引擎
let PuppeteerEngine: any = null;
let PlaywrightEngine: any = null;
let SeleniumEngine: any = null;

export class EngineFactory {
  private engines = new Map<string, ICrawlerEngine>();
  private isInitialized = false;

  async initialize(): Promise<void> {
    if (this.isInitialized) return;

    try {
      // 注册HTTP引擎（总是可用）
      this.registerEngine('http', new HttpEngine());

      // 尝试注册可选引擎
      await this.tryRegisterOptionalEngines();

      this.isInitialized = true;
      logger.info(`✅ Engine factory initialized with engines: ${this.getAvailableEngines().join(', ')}`);
    } catch (error) {
      logger.error('❌ Failed to initialize engine factory:', error);
      throw error;
    }
  }

  private async tryRegisterOptionalEngines(): Promise<void> {
    // 尝试注册 Puppeteer 引擎
    try {
      const { PuppeteerEngine: PuppeteerEngineClass } = await import('./PuppeteerEngine.js');
      PuppeteerEngine = PuppeteerEngineClass;
      this.registerEngine('puppeteer', new PuppeteerEngine());
      logger.info('✅ Puppeteer engine registered');
    } catch (error) {
      logger.warn('⚠️ Puppeteer engine not available:', error instanceof Error ? error.message : String(error));
    }

    // 尝试注册 Playwright 引擎
    try {
      const { PlaywrightEngine: PlaywrightEngineClass } = await import('./PlaywrightEngine.js');
      PlaywrightEngine = PlaywrightEngineClass;
      this.registerEngine('playwright', new PlaywrightEngine());
      logger.info('✅ Playwright engine registered');
    } catch (error) {
      logger.warn('⚠️ Playwright engine not available:', error instanceof Error ? error.message : String(error));
    }

    // 尝试注册 Selenium 引擎
    try {
      const { SeleniumEngine: SeleniumEngineClass } = await import('./SeleniumEngine.js');
      SeleniumEngine = SeleniumEngineClass;
      this.registerEngine('selenium', new SeleniumEngine());
      logger.info('✅ Selenium engine registered');
    } catch (error) {
      logger.warn('⚠️ Selenium engine not available:', error instanceof Error ? error.message : String(error));
    }
  }

  registerEngine(name: string, engine: ICrawlerEngine): void {
    this.engines.set(name, engine);
  }

  async getEngine(name: string): Promise<ICrawlerEngine> {
    const engine = this.engines.get(name);
    if (!engine) {
      throw new Error(`Engine '${name}' not found. Available engines: ${this.getAvailableEngines().join(', ')}`);
    }

    // 检查引擎是否可用
    const isAvailable = await engine.isAvailable();
    if (!isAvailable) {
      throw new Error(`Engine '${name}' is not available`);
    }

    return engine;
  }

  getAvailableEngines(): string[] {
    return Array.from(this.engines.keys());
  }

  async getEngineStatus(): Promise<Record<string, boolean>> {
    const status: Record<string, boolean> = {};

    for (const [name, engine] of Array.from(this.engines.entries())) {
      try {
        status[name] = await engine.isAvailable();
      } catch (error) {
        status[name] = false;
      }
    }

    return status;
  }

  async cleanup(): Promise<void> {
    logger.info('🧹 Cleaning up engines...');

    for (const [name, engine] of Array.from(this.engines.entries())) {
      try {
        await engine.cleanup();
        logger.info(`✅ Engine '${name}' cleaned up`);
      } catch (error) {
        logger.error(`❌ Failed to cleanup engine '${name}':`, error);
      }
    }

    this.engines.clear();
    this.isInitialized = false;
  }
}
